package com.wxx.ws;

import com.alibaba.fastjson2.JSON;
import com.wxx.config.GetHttpSessionConfig;
import com.wxx.utils.MessageUtils;
import com.wxx.ws.pojo.Message;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
public class ChatEndpoint {

    //保存在线的用户 key为用户名 value为Session对象
    private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();

    private HttpSession httpSession;

    /**
     * 建立websocket连接后 被调用
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());

        String user = (String) this.httpSession.getAttribute("currentUser");
        if (user != null) {
            onlineUsers.put(user, session);
        }

        //通知所有用户 当前用户上线了
        String message = MessageUtils.getMessage(true, null, getFriends());
        broadCastAllUsers(message);
    }

    private void broadCastAllUsers(String message) {
        try {
            Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();

            for (Map.Entry<String, Session> entry : entries) {
                //获取到所有用户对应的session对象
                Session session = entry.getValue();
                //使用getBasicRemote()方法发送同步消息
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Set<String> getFriends() {
        return onlineUsers.keySet();
    }

    /**
     * 浏览器发送消息到服务端时会调用该方法 也就是私聊  张三 --> 李四
     */
    @OnMessage
    public void onMessage(String message) {
        try {
            //将消息推送给指定的用户
            Message msg = JSON.parseObject(message, Message.class);
            String toName = msg.getToName();
            String tempMsg = msg.getMessage();

            //获取消息接收方用户对象的session对象
            Session session = onlineUsers.get(toName);
            String currentUser = (String) this.httpSession.getAttribute("currentUser");
            String messageToSend = MessageUtils.getMessage(false, currentUser, tempMsg);

            session.getBasicRemote().sendText(messageToSend);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 断开websocket连接时调用
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        //从onlineUsers中删除当前用户的session对象 表示当前用户已下线
        String user = (String) this.httpSession.getAttribute("currentUser");
        if (user != null) {
            Session remove = onlineUsers.remove(user);
            if (remove != null) {
                remove.close();
            }
            session.close();
        }

        //通知其他用户 当前用户已下线
        //这里不是发送类似xxx已下线的消息 而是向在线用户重新发送一次在线的所有用户
        String message = MessageUtils.getMessage(true, null, getFriends());
        broadCastAllUsers(message);
    }

}
